<!DOCTYPE html>
<html>

  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<meta http-equiv="Cache-Control" content="no-siteapp" />

    <title>xmake从入门到精通12：通过自定义脚本实现更灵活地配置</title>
    <meta name="description" content="xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具，主要特点是：语法简单易上手，提供更加可读的项目维护，实现跨平台行为一致的构建体验。本文主要详细讲解下，如何通过添加自定义的脚本，在脚本域实现更加复杂灵活的定制。  项目源码  官方文档配置分离xmake.lua采用二八原则实现了描述域、脚本域两层分...">

    
    <meta name="keywords" content="xmake,lua,子工程,子模块,自定义脚本,tboox" /> 

    <!-- qq oauth -->
    <meta property="qc:admins" content="5211601217706727767255" />

    <!--icon -->
    <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon">
    <link rel="icon" sizes="192x192" href="/static/img/nice-highres.png" />
	<link rel="apple-touch-icon-precomposed" href="/static/img/apple-touch-icon-57x57-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="72x72" href="/static/img/apple-touch-icon-72x72-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="114x114" href="/static/img/apple-touch-icon-114x114-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="144x144" href="/static/img/apple-touch-icon-144x144-precomposed.png" />
	<link rel="apple-touch-icon-precomposed" sizes="180x180" href="/static/img/retinahd_icon.png" />
	<meta name="msapplication-TileImage" content="/static/img/retinahd_icon.png" />
	
    <link rel="stylesheet" href=" /css/fontawesome/css/font-awesome.min.css ">
    <link rel="stylesheet" href=" /css/main.css ">
    <link rel="canonical" href="https://tboox.org/cn/2020/07/18/quickstart-12-custom-scripts/">
    <link rel="alternate" type="application/rss+xml" title="TBOOX Open Source Project" href="https://tboox.org/feed.xml ">
    <link rel="alternate" hreflang="en" href="https://tboox.org/" />
    <link rel="alternate" hreflang="zh-Hans" href="https://tboox.org/cn/" />

    <!-- css -->
    <link href="/css/reward.css" rel="stylesheet" type="text/css"> 




    <script type="text/javascript">
    function isPC(){    
        var userAgentInfo = navigator.userAgent;  
        var Agents = new Array("Android", "iPhone", "SymbianOS", "Windows Phone", "iPad", "iPod");    
        var flag = true;    
        for (var v = 0; v < Agents.length; v++) {    
            if (userAgentInfo.indexOf(Agents[v]) > 0) { flag = false; break; }    
        }    
        return flag;    
    }
    </script>

<!-- baidu ads -->



    <!-- baidu ads -->

</head>


  <body>

    <header id="top">
    <div class="wrapper">
        <a href="/cn" class="brand">TBOOX</a>
        <button id="headerMenu" class="menu"><i class="fa fa-bars"></i></button>
        <nav id="headerNav">
            <ul>
                <li>
                    
                    <a href="/?lang=0">
                    
                        <i class="fa fa-home"></i>English
                    </a>
                </li>

                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/project/">
                            
                        
                            <i class="fa fa-bookmark"></i>项目
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/archive/">
                            
                        
                            <i class="fa fa-archive"></i>归档
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/category/">
                            
                        
                            <i class="fa fa-th-list"></i>分类
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/tag/">
                            
                        
                            <i class="fa fa-tags"></i>标记
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/docs/">
                            
                        
                            <i class="fa fa-book"></i>文档
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="https://xmake.io/#/zh-cn/about/contact" target="_blank" >
                            
                        
                            <i class="fa fa-forumbee"></i>社区
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/donation/">
                            
                        
                            <i class="fa fa-heart"></i>捐助
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                    
                    <li>
                        
                            
                            <a href="/cn/about/">
                            
                        
                            <i class="fa fa-user"></i>关于
                        </a>
                    </li>
                    
                    
                
                    
                    
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                    
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
                    
                
            </ul>
        </nav>
    </div>
</header>



        <div class="page clearfix" post>
    <div class="left">
        <h1>xmake从入门到精通12：通过自定义脚本实现更灵活地配置</h1>
        <div class="label">

            <div class="label-card">
                <i class="fa fa-calendar"></i>2020-07-18
            </div>

            <div class="label-card">
                
            </div>

            <div class="label-card">
                
            </div>

            <div class="label-card">
            


<!-- <span class="point">•</span> -->
<span class="categories">
  <i class="fa fa-th-list"></i>
  
    
        <a href="/category/#xmake" title="Category: xmake" rel="category">xmake</a>
    
  

  <!-- <span class="point">•</span> -->
</span>


            </div>

            <div class="label-card">
            
<!-- <span class="point">•</span> -->
<span class="pageTag">
  <i class="fa fa-tags"></i>
  
    
        <!--a href="/tag/#xmake" title="Tag: xmake" rel="tag">xmake</a-->
        <a href="/cn/tag/#xmake" title="Tag: xmake" rel="tag">xmake</a>&nbsp;
    
        <!--a href="/tag/#lua" title="Tag: lua" rel="tag">lua</a-->
        <a href="/cn/tag/#lua" title="Tag: lua" rel="tag">lua</a>&nbsp;
    
        <!--a href="/tag/#%E5%AD%90%E5%B7%A5%E7%A8%8B" title="Tag: 子工程" rel="tag">子工程</a-->
        <a href="/cn/tag/#子工程" title="Tag: 子工程" rel="tag">子工程</a>&nbsp;
    
        <!--a href="/tag/#%E5%AD%90%E6%A8%A1%E5%9D%97" title="Tag: 子模块" rel="tag">子模块</a-->
        <a href="/cn/tag/#子模块" title="Tag: 子模块" rel="tag">子模块</a>&nbsp;
    
        <!--a href="/tag/#%E8%87%AA%E5%AE%9A%E4%B9%89%E8%84%9A%E6%9C%AC" title="Tag: 自定义脚本" rel="tag">自定义脚本</a-->
        <a href="/cn/tag/#自定义脚本" title="Tag: 自定义脚本" rel="tag">自定义脚本</a>
    
  

</span>

            </div>

        </div>
        <hr>
        <article itemscope itemtype="http://schema.org/BlogPosting">
        <p>xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具，主要特点是：语法简单易上手，提供更加可读的项目维护，实现跨平台行为一致的构建体验。</p>

<p>本文主要详细讲解下，如何通过添加自定义的脚本，在脚本域实现更加复杂灵活的定制。</p>

<ul>
  <li><a href="https://github.com/xmake-io/xmake">项目源码</a></li>
  <li><a href="https://xmake.io/#/zh-cn/">官方文档</a></li>
</ul>

<h3 id="配置分离">配置分离</h3>

<p>xmake.lua采用二八原则实现了描述域、脚本域两层分离式配置。</p>

<p>什么是二八原则呢，简单来说，大部分项目的配置，80%的情况下，都是些基础的常规配置，比如：<code class="highlighter-rouge">add_cxflags</code>, <code class="highlighter-rouge">add_links</code>等，
只有剩下不到20%的地方才需要额外做些复杂来满足一些特殊的配置需求。</p>

<p>而这剩余的20%的配置通常比较复杂，如果直接充斥在整个xmake.lua里面，会把整个项目的配置整个很混乱，非常不可读。</p>

<p>因此，xmake通过描述域、脚本域两种不同的配置方式，来隔离80%的简单配置以及20%的复杂配置，使得整个xmake.lua看起来非常的清晰直观，可读性和可维护性都达到最佳。</p>

<h3 id="描述域">描述域</h3>

<p>对于刚入门的新手用户，或者仅仅是维护一些简单的小项目，通过完全在描述配置就已经完全满足需求了，那什么是描述域呢？它长这样：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"DEBUG"</span><span class="p">)</span>
    <span class="n">add_syslinks</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">)</span>
</code></pre>
</div>

<p>一眼望去，其实就是个 <code class="highlighter-rouge">set_xxx</code>/<code class="highlighter-rouge">add_xxx</code>的配置集，对于新手，完全可以不把它当做lua脚本，仅仅作为普通的，但有一些基础规则的配置文件就行了。</p>

<p>这是不是看着更像配置文件了？其实描述域就是配置文件，类似像json等key/values的配置而已，所以即使完全不会lua的新手，也是能很快上手的。</p>

<p>而且，对于通常的项目，仅通过<code class="highlighter-rouge">set_xxx/add_xxx</code>去配置各种项目设置，已经完全满足需求了。</p>

<p>这也就是开头说的：80%的情况下，可以用最简单的配置规则去简化项目的配置，提高可读性和可维护性，这样对用户和开发者都会非常的友好，也更加直观。</p>

<p>如果我们要针对不同平台，架构做一些条件判断怎么办？没关系，描述域除了基础配置，也是支持条件判断，以及for循环的：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"DEBUG"</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">is_plat</span><span class="p">(</span><span class="s2">"linux"</span><span class="p">,</span> <span class="s2">"macosx"</span><span class="p">)</span> <span class="k">then</span>
        <span class="n">add_links</span><span class="p">(</span><span class="s2">"pthread"</span><span class="p">,</span> <span class="s2">"m"</span><span class="p">,</span> <span class="s2">"dl"</span><span class="p">)</span>
    <span class="k">end</span>
</code></pre>
</div>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">add_defines</span><span class="p">(</span><span class="s2">"DEBUG"</span><span class="p">)</span>
    <span class="k">for</span> <span class="n">_</span><span class="p">,</span> <span class="n">name</span> <span class="k">in</span> <span class="nb">ipairs</span><span class="p">({</span><span class="s2">"pthread"</span><span class="p">,</span> <span class="s2">"m"</span><span class="p">,</span> <span class="s2">"dl"</span><span class="p">})</span> <span class="k">do</span>
        <span class="n">add_links</span><span class="p">(</span><span class="n">name</span><span class="p">)</span>
    <span class="k">end</span>
</code></pre>
</div>

<p>这是不是看着有点像lua了？虽说，平常可以把它当做普通配置问题，但是xmake毕竟基于lua，所以描述域还是支持lua的基础语言特性的。</p>

<p>!&gt; 不过需要注意的是，描述域虽然支持lua的脚本语法，但在描述域尽量不要写太复杂的lua脚本，比如一些耗时的函数调用和for循环</p>

<p>并且在描述域，主要目的是为了设置配置项，因此xmake并没有完全开放所有的模块接口，很多接口在描述域是被禁止调用的，
即使开放出来的一些可调用接口，也是完全只读的，不耗时的安全接口，比如：<code class="highlighter-rouge">os.getenv()</code>等读取一些常规的系统信息，用于配置逻辑的控制。</p>

<p>!&gt; 另外需要注意一点，xmake.lua是会被多次解析的，用于在不同阶段解析不同的配置域：比如：<code class="highlighter-rouge">option()</code>, <code class="highlighter-rouge">target()</code>等域。</p>

<p>因此，不要想着在xmake.lua的描述域，写复杂的lua脚本，也不要在描述域调用print去显示信息，因为会被执行多遍，记住：会被执行多遍！！！</p>

<h3 id="脚本域">脚本域</h3>

<p>限制描述域写复杂的lua，各种lua模块和接口都用不了？怎么办？这个时候就是脚本域出场的时候了。</p>

<p>如果用户已经完全熟悉了xmake的描述域配置，并且感觉有些满足不了项目上的一些特殊配置维护了，那么我们可以在脚本域做更加复杂的配置逻辑：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">on_load</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="k">if</span> <span class="n">is_plat</span><span class="p">(</span><span class="s2">"linux"</span><span class="p">,</span> <span class="s2">"macosx"</span><span class="p">)</span> <span class="k">then</span>
            <span class="n">target</span><span class="p">:</span><span class="n">add</span><span class="p">(</span><span class="s2">"links"</span><span class="p">,</span> <span class="s2">"pthread"</span><span class="p">,</span> <span class="s2">"m"</span><span class="p">,</span> <span class="s2">"dl"</span><span class="p">)</span>
        <span class="k">end</span>
    <span class="k">end</span><span class="p">)</span>
    <span class="n">after_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">import</span><span class="p">(</span><span class="s2">"core.project.config"</span><span class="p">)</span>
        <span class="kd">local</span> <span class="n">targetfile</span> <span class="o">=</span> <span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">()</span>
        <span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="n">targetfile</span><span class="p">,</span> <span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="n">config</span><span class="p">.</span><span class="n">buildir</span><span class="p">(),</span> <span class="n">path</span><span class="p">.</span><span class="n">filename</span><span class="p">(</span><span class="n">targetfile</span><span class="p">)))</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"build %s"</span><span class="p">,</span> <span class="n">targetfile</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>只要是类似：<code class="highlighter-rouge">on_xxx</code>, <code class="highlighter-rouge">after_xxx</code>, <code class="highlighter-rouge">before_xxx</code>等字样的function body内部的脚本，都属于脚本域。</p>

<p>在脚本域中，用户可以干任何事，xmake提供了import接口可以导入xmake内置的各种lua模块，也可以导入用户提供的lua脚本。</p>

<p>我们可以在脚本域实现你想实现的任意功能，甚至写个独立项目出来都是可以的。</p>

<p>对于一些脚本片段，不是很臃肿的话，像上面这么内置写写就足够了，如果需要实现更加复杂的脚本，不想充斥在一个xmake.lua里面，可以把脚本分离到独立的lua文件中去维护。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">on_load</span><span class="p">(</span><span class="s2">"modules.test.load"</span><span class="p">)</span>
    <span class="n">on_install</span><span class="p">(</span><span class="s2">"modules.test.install"</span><span class="p">)</span>
</code></pre>
</div>

<p>我们可以吧自定义的脚本放置到xmake.lua对应目录下，<code class="highlighter-rouge">modules/test/load.lua</code>和<code class="highlighter-rouge">modules/test/install.lua</code>中独立维护。</p>

<p>单独的lua脚本文件以main作为主入口，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 我们也可以在此处导入一些内置模块或者自己的扩展模块来使用</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"core.project.config"</span><span class="p">)</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"mymodule"</span><span class="p">)</span>

<span class="k">function</span> <span class="nf">main</span><span class="p">(</span><span class="n">target</span><span class="p">)</span>
    <span class="k">if</span> <span class="n">is_plat</span><span class="p">(</span><span class="s2">"linux"</span><span class="p">,</span> <span class="s2">"macosx"</span><span class="p">)</span> <span class="k">then</span>
        <span class="n">target</span><span class="p">:</span><span class="n">add</span><span class="p">(</span><span class="s2">"links"</span><span class="p">,</span> <span class="s2">"pthread"</span><span class="p">,</span> <span class="s2">"m"</span><span class="p">,</span> <span class="s2">"dl"</span><span class="p">)</span>
    <span class="k">end</span>
<span class="k">end</span>
</code></pre>
</div>

<p>这些独立的lua脚本里面，我们还可以通过<a href="https://xmake.io/#/zh-cn/manual/builtin_modules?id=import">import</a>导入各种内置模块和自定义模块进来使用，就跟平常写lua, java没啥区别。</p>

<p>而对于脚本的域的不同阶段，<code class="highlighter-rouge">on_load</code>主要用于target加载时候，做一些动态化的配置，这里不像描述域，只会执行一遍哦!!!</p>

<p>其他阶段，还有很多，比如：<code class="highlighter-rouge">on/after/before</code>_<code class="highlighter-rouge">build/install/package/run</code>等，我们下面会详细描述。</p>

<h3 id="import">import</h3>

<h4 id="导入扩展摸块">导入扩展摸块</h4>

<p>在讲解各个脚本域之前，我们先来简单介绍下xmake的模块导入和使用方式，xmake采用import来引入其他的扩展模块，以及用户自己定义的模块，它可以在下面一些地方使用：</p>

<ul>
  <li>自定义脚本(<a href="https://xmake.io/#/zh-cn/manual/project_target?id=targeton_build">on_build</a>, <a href="https://xmake.io/#/zh-cn/manual/project_target?id=targeton_run">on_run</a> ..)</li>
  <li>插件开发</li>
  <li>模板开发</li>
  <li>平台扩展</li>
  <li>自定义任务task</li>
</ul>

<p>导入机制如下：</p>

<ol>
  <li>优先从当前脚本目录下导入</li>
  <li>再从扩展类库中导入</li>
</ol>

<p>导入的语法规则：</p>

<p>基于<code class="highlighter-rouge">.</code>的类库路径规则，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"core.base.option"</span><span class="p">)</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"core.base.task"</span><span class="p">)</span>

<span class="k">function</span> <span class="nf">main</span><span class="p">()</span>
    
    <span class="c1">-- 获取参数选项</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">option</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"version"</span><span class="p">))</span>

    <span class="c1">-- 运行任务和插件</span>
    <span class="n">task</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"hello"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>导入当前目录下的自定义模块：</p>

<p>目录结构：</p>

<div class="highlighter-rouge"><pre class="highlight"><code>plugin
  - xmake.lua
  - main.lua
  - modules
    - hello1.lua
    - hello2.lua
</code></pre>
</div>

<p>在main.lua中导入modules</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"modules.hello1"</span><span class="p">)</span>
<span class="n">import</span><span class="p">(</span><span class="s2">"modules.hello2"</span><span class="p">)</span>
</code></pre>
</div>

<p>导入后就可以直接使用里面的所有公有接口，私有接口用<code class="highlighter-rouge">_</code>前缀标示，表明不会被导出，不会被外部调用到。。</p>

<p>除了当前目录，我们还可以导入其他指定目录里面的类库，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"hello3"</span><span class="p">,</span> <span class="p">{</span><span class="n">rootdir</span> <span class="o">=</span> <span class="s2">"/home/xxx/modules"</span><span class="p">})</span>
</code></pre>
</div>

<p>为了防止命名冲突，导入后还可以指定的别名：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">import</span><span class="p">(</span><span class="s2">"core.platform.platform"</span><span class="p">,</span> <span class="p">{</span><span class="n">alias</span> <span class="o">=</span> <span class="s2">"p"</span><span class="p">})</span>

<span class="k">function</span> <span class="nf">main</span><span class="p">()</span>
    <span class="c1">-- 这样我们就可以使用p来调用platform模块的plats接口，获取所有xmake支持的平台列表了</span>
    <span class="nb">print</span><span class="p">(</span><span class="n">p</span><span class="p">.</span><span class="n">plats</span><span class="p">())</span>
<span class="k">end</span>
</code></pre>
</div>

<p>2.1.5版本新增两个新属性：<code class="highlighter-rouge">import("xxx.xxx", {try = true, anonymous = true})</code></p>

<p>try为true，则导入的模块不存在的话，仅仅返回nil，并不会抛异常后中断xmake.
anonymous为true，则导入的模块不会引入当前作用域，仅仅在import接口返回导入的对象引用。</p>

<h3 id="测试扩展模块">测试扩展模块</h3>

<p>一种方式我们可以在on_load等脚本中，直接调用print去打印模块的调用结果信息，来测试和验证。</p>

<p>不过xmake还提供了<code class="highlighter-rouge">xmake lua</code>插件可以更加灵活方便的测试脚本。</p>

<h4 id="运行指定的脚本文件">运行指定的脚本文件</h4>

<p>比如，我们可以直接指定lua脚本来加载运行，这对于想要快速测试一些接口模块，验证自己的某些思路，都是一个不错的方式。</p>

<p>我们先写个简单的lua脚本：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="k">function</span> <span class="nf">main</span><span class="p">()</span>
    <span class="nb">print</span><span class="p">(</span><span class="s2">"hello xmake!"</span><span class="p">)</span>
<span class="k">end</span>
</code></pre>
</div>

<p>然后直接运行它就行了：</p>

<div class="language-console highlighter-rouge"><pre class="highlight"><code><span class="w">$ </span><span class="nc">xmake</span><span class="kv"> lua /tmp/test.lua
</span></code></pre>
</div>

<h4 id="直接调用扩展模块">直接调用扩展模块</h4>

<p>所有内置模块和扩展模块的接口，我们都可以通过<code class="highlighter-rouge">xmake lua</code>直接调用，例如：</p>

<div class="language-console highlighter-rouge"><pre class="highlight"><code><span class="w">$ </span><span class="nc">xmake</span><span class="kv"> lua lib.detect.find_tool gcc
</span></code></pre>
</div>

<p>上面的命令，我们直接调用了<code class="highlighter-rouge">import("lib.detect.find_tool")</code>模块接口来快速执行。</p>

<h4 id="运行交互命令-repl">运行交互命令 (REPL)</h4>

<p>有时候在交互模式下，运行命令更加的方便测试和验证一些模块和api，也更加的灵活，不需要再去额外写一个脚本文件来加载。</p>

<p>我们先看下，如何进入交互模式：</p>

<div class="language-console highlighter-rouge"><pre class="highlight"><code><span class="ni"># </span><span class="nc">不带任何参数执行，就可以进入</span><span class="kv">
</span><span class="w">$ </span><span class="nc">xmake</span><span class="kv"> lua
</span>&gt;

<span class="ni"># </span><span class="nc">进行表达式计算</span><span class="kv">
</span>&gt; 1 + 2
3

<span class="ni"># </span><span class="nc">赋值和打印变量值</span><span class="kv">
</span>&gt; a = 1
&gt; a
1

<span class="ni"># </span><span class="nc">多行输入和执行</span><span class="kv">
</span>&gt; for _, v in pairs({1, 2, 3}) do
&gt;&gt; print(v)
&gt;&gt; end
1
2
3
</code></pre>
</div>

<p>我们也能够通过 <code class="highlighter-rouge">import</code> 来导入扩展模块：</p>

<div class="language-console highlighter-rouge"><pre class="highlight"><code>&gt; task = import("core.project.task")
&gt; task.run("hello")
hello xmake!
</code></pre>
</div>

<p>如果要中途取消多行输入，只需要输入字符：<code class="highlighter-rouge">q</code> 就行了</p>

<div class="language-console highlighter-rouge"><pre class="highlight"><code>&gt; for _, v in ipairs({1, 2}) do
&gt;&gt; print(v)
&gt;&gt; q             &lt;--  取消多行输入，清空先前的输入数据
&gt; 1 + 2
3
</code></pre>
</div>

<h3 id="targeton_load">target:on_load</h3>

<h4 id="自定义目标加载脚本">自定义目标加载脚本</h4>

<p>在target初始化加载的时候，将会执行此脚本，在里面可以做一些动态的目标配置，实现更灵活的目标描述定义，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_load</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="n">target</span><span class="p">:</span><span class="n">add</span><span class="p">(</span><span class="s2">"defines"</span><span class="p">,</span> <span class="s2">"DEBUG"</span><span class="p">,</span> <span class="s2">"TEST=\"</span><span class="n">hello</span><span class="err">\</span><span class="s2">""</span><span class="p">)</span>
        <span class="n">target</span><span class="p">:</span><span class="n">add</span><span class="p">(</span><span class="s2">"linkdirs"</span><span class="p">,</span> <span class="s2">"/usr/lib"</span><span class="p">,</span> <span class="s2">"/usr/local/lib"</span><span class="p">)</span>
        <span class="n">target</span><span class="p">:</span><span class="n">add</span><span class="p">({</span><span class="n">includedirs</span> <span class="o">=</span> <span class="s2">"/usr/include"</span><span class="p">,</span> <span class="s2">"links"</span> <span class="o">=</span> <span class="s2">"pthread"</span><span class="p">})</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>可以在<code class="highlighter-rouge">on_load</code>里面，通过<code class="highlighter-rouge">target:set</code>, <code class="highlighter-rouge">target:add</code> 来动态添加各种target属性，所有描述域的<code class="highlighter-rouge">set_</code>, <code class="highlighter-rouge">add_</code>配置都可以通过这种方式动态配置。</p>

<p>另外，我们可以调用target的一些接口，获取和设置一些基础信息，比如：</p>

<table>
  <thead>
    <tr>
      <th>target接口</th>
      <th>描述</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>target:name()</td>
      <td>获取目标名</td>
    </tr>
    <tr>
      <td>target:targetfile()</td>
      <td>获取目标文件路径</td>
    </tr>
    <tr>
      <td>target:targetkind()</td>
      <td>获取目标的构建类型</td>
    </tr>
    <tr>
      <td>target:get(“defines”)</td>
      <td>获取目标的宏定义</td>
    </tr>
    <tr>
      <td>target:get(“xxx”)</td>
      <td>其他通过 <code class="highlighter-rouge">set_/add_</code>接口设置的target信息，都可以通过此接口来获取</td>
    </tr>
    <tr>
      <td>target:add(“links”, “pthread”)</td>
      <td>添加目标设置</td>
    </tr>
    <tr>
      <td>target:set(“links”, “pthread”, “z”)</td>
      <td>覆写目标设置</td>
    </tr>
    <tr>
      <td>target:deps()</td>
      <td>获取目标的所有依赖目标</td>
    </tr>
    <tr>
      <td>target:dep(“depname”)</td>
      <td>获取指定的依赖目标</td>
    </tr>
    <tr>
      <td>target:opts()</td>
      <td>获取目标的所有关联选项</td>
    </tr>
    <tr>
      <td>target:opt(“optname”)</td>
      <td>获取指定的关联选项</td>
    </tr>
    <tr>
      <td>target:pkgs()</td>
      <td>获取目标的所有关联依赖包</td>
    </tr>
    <tr>
      <td>target:pkg(“pkgname”)</td>
      <td>获取指定的关联依赖包</td>
    </tr>
    <tr>
      <td>target:sourcebatches()</td>
      <td>获取目标的所有源文件列表</td>
    </tr>
  </tbody>
</table>

<h3 id="targeton_link">target:on_link</h3>

<h4 id="自定义链接脚本">自定义链接脚本</h4>

<p>这个是在v2.2.7之后新加的接口，用于定制化处理target的链接过程。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_link</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 
        <span class="nb">print</span><span class="p">(</span><span class="s2">"link it"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h3 id="targeton_build">target:on_build</h3>

<h4 id="自定义编译脚本">自定义编译脚本</h4>

<p>覆盖target目标默认的构建行为，实现自定义的编译过程，一般情况下，并不需要这么做，除非确实需要做一些xmake默认没有提供的编译操作。</p>

<p>你可以通过下面的方式覆盖它，来自定义编译操作：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 设置自定义编译脚本</span>
    <span class="n">on_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 
        <span class="nb">print</span><span class="p">(</span><span class="s2">"build it"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>注：2.1.5版本之后，所有target的自定义脚本都可以针对不同平台和架构，分别处理，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="s2">"iphoneos|arm*"</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"build for iphoneos and arm"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>其中如果第一个参数为字符串，那么就是指定这个脚本需要在哪个<code class="highlighter-rouge">平台|架构</code>下，才会被执行，并且支持模式匹配，例如<code class="highlighter-rouge">arm*</code>匹配所有arm架构。</p>

<p>当然也可以只设置平台，不设置架构，这样就是匹配指定平台下，执行脚本：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_build</span><span class="p">(</span><span class="s2">"windows"</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">"build for windows"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>注：一旦对这个target目标设置了自己的build过程，那么xmake默认的构建过程将不再被执行。</p>

<h3 id="targeton_build_file">target:on_build_file</h3>

<h4 id="自定义编译脚本-实现单文件构建">自定义编译脚本, 实现单文件构建</h4>

<p>通过此接口，可以用来hook指定target内置的构建过程，自己重新实现每个源文件编译过程：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">on_build_file</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcefile</span><span class="p">,</span> <span class="n">opt</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h3 id="targeton_build_files">target:on_build_files</h3>

<h4 id="自定义编译脚本-实现多文件构建">自定义编译脚本, 实现多文件构建</h4>

<p>通过此接口，可以用来hook指定target内置的构建过程，替换一批同类型源文件编译过程：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"binary"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"src/*.c"</span><span class="p">)</span>
    <span class="n">on_build_files</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">,</span> <span class="n">sourcebatch</span><span class="p">,</span> <span class="n">opt</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>设置此接口后，对应源文件列表中文件，就不会出现在自定义的target.on_build_file了，因为这个是包含关系。</p>

<p>其中sourcebatch描述了这批同类型源文件：</p>

<ul>
  <li><code class="highlighter-rouge">sourcebatch.sourcekind</code>: 获取这批源文件的类型，比如：cc, as, ..</li>
  <li><code class="highlighter-rouge">sourcebatch.sourcefiles()</code>: 获取源文件列表</li>
  <li><code class="highlighter-rouge">sourcebatch.objectfiles()</code>: 获取对象文件列表</li>
  <li><code class="highlighter-rouge">sourcebatch.dependfiles()</code>: 获取对应依赖文件列表，存有源文件中编译依赖信息，例如：xxx.d</li>
</ul>

<h3 id="targeton_clean">target:on_clean</h3>

<h4 id="自定义清理脚本">自定义清理脚本</h4>

<p>覆盖target目标的<code class="highlighter-rouge">xmake [c|clean}</code>的清理操作，实现自定义清理过程。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 设置自定义清理脚本</span>
    <span class="n">on_clean</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 

        <span class="c1">-- 仅删掉目标文件</span>
        <span class="n">os</span><span class="p">.</span><span class="n">rm</span><span class="p">(</span><span class="n">target</span><span class="p">:</span><span class="n">targetfile</span><span class="p">())</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h3 id="targeton_package">target:on_package</h3>

<h4 id="自定义打包脚本">自定义打包脚本</h4>

<p>覆盖target目标的<code class="highlighter-rouge">xmake [p|package}</code>的打包操作，实现自定义打包过程，如果你想对指定target打包成自己想要的格式，可以通过这个接口自定义它。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"demo"</span><span class="p">)</span>
    <span class="n">set_kind</span><span class="p">(</span><span class="s2">"shared"</span><span class="p">)</span>
    <span class="n">add_files</span><span class="p">(</span><span class="s2">"jni/*.c"</span><span class="p">)</span>
    <span class="n">on_package</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 
        <span class="n">os</span><span class="p">.</span><span class="n">exec</span><span class="p">(</span><span class="s2">"./gradlew app:assembleDebug"</span><span class="p">)</span> 
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<p>当然这个例子有点老了，这里只是举例说明下用法而已，现在xmake提供了专门的<a href="https://github.com/xmake-io/xmake-gradle">xmake-gradle</a>插件，来与gradle更好的集成。</p>

<h3 id="targeton_install">target:on_install</h3>

<h4 id="自定义安装脚本">自定义安装脚本</h4>

<p>覆盖target目标的<code class="highlighter-rouge">xmake [i|install}</code>的安装操作，实现自定义安装过程。</p>

<p>例如，将生成的apk包，进行安装。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 设置自定义安装脚本，自动安装apk文件</span>
    <span class="n">on_install</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 

        <span class="c1">-- 使用adb安装打包生成的apk文件</span>
        <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"adb install -r ./bin/Demo-debug.apk"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h3 id="targeton_uninstall">target:on_uninstall</h3>

<h4 id="自定义卸载脚本">自定义卸载脚本</h4>

<p>覆盖target目标的<code class="highlighter-rouge">xmake [u|uninstall}</code>的卸载操作，实现自定义卸载过程。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">on_uninstall</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 
        <span class="o">...</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h3 id="targeton_run">target:on_run</h3>

<h4 id="自定义运行脚本">自定义运行脚本</h4>

<p>覆盖target目标的<code class="highlighter-rouge">xmake [r|run}</code>的运行操作，实现自定义运行过程。</p>

<p>例如，运行安装好的apk程序：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>

    <span class="c1">-- 设置自定义运行脚本，自动运行安装好的app程序，并且自动获取设备输出信息</span>
    <span class="n">on_run</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span> 
        <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"adb shell am start -n com.demo/com.demo.DemoTest"</span><span class="p">)</span>
        <span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"adb logcat"</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h3 id="before_xxx和after_xxx">before_xxx和after_xxx</h3>

<p>需要注意的是，target:on_xxx的所有接口都覆盖内部默认实现，通常我们并不需要完全复写，只是额外挂接自己的一些逻辑，那么可以使用<code class="highlighter-rouge">target:before_xxx</code>和<code class="highlighter-rouge">target:after_xxx</code>系列脚本就行了。</p>

<p>所有的on_xxx都有对应的before_和after_xx版本，参数也完全一致，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">target</span><span class="p">(</span><span class="s2">"test"</span><span class="p">)</span>
    <span class="n">before_build</span><span class="p">(</span><span class="k">function</span> <span class="p">(</span><span class="n">target</span><span class="p">)</span>
        <span class="nb">print</span><span class="p">(</span><span class="s2">""</span><span class="p">)</span>
    <span class="k">end</span><span class="p">)</span>
</code></pre>
</div>

<h3 id="内置模块">内置模块</h3>

<p>在自定义脚本中，除了使用import接口导入各种扩展模块使用，xmake还提供了很多基础的内置模块，比如：os，io等基础操作，实现更加跨平台的处理系统接口。</p>

<h4 id="oscp">os.cp</h4>

<p>os.cp的行为和shell中的<code class="highlighter-rouge">cp</code>命令类似，不过更加强大，不仅支持模式匹配（使用的是lua模式匹配），而且还确保目的路径递归目录创建、以及支持xmake的内置变量。</p>

<p>例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="s2">"$(scriptdir)/*.h"</span><span class="p">,</span> <span class="s2">"$(buildir)/inc"</span><span class="p">)</span>
<span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="s2">"$(projectdir)/src/test/**.h"</span><span class="p">,</span> <span class="s2">"$(buildir)/inc"</span><span class="p">)</span>
</code></pre>
</div>

<p>上面的代码将：当前<code class="highlighter-rouge">xmake.lua</code>目录下的所有头文件、工程源码test目录下的头文件全部复制到<code class="highlighter-rouge">$(buildir)</code>输出目录中。</p>

<p>其中<code class="highlighter-rouge">$(scriptdir)</code>, <code class="highlighter-rouge">$(projectdir)</code> 这些变量是xmake的内置变量，具体详情见：<a href="https://xmake.io/mirror/zh-cn/manual/builtin_variables.html">内置变量</a>的相关文档。</p>

<p>而<code class="highlighter-rouge">*.h</code>和<code class="highlighter-rouge">**.h</code>中的匹配模式，跟<a href="https://xmake.io/#/zh-cn/manual/project_target?id=targetadd_files">add_files</a>中的类似，前者是单级目录匹配，后者是递归多级目录匹配。</p>

<p>上面的复制，会把所有文件全部展开复制到指定目录，丢失源目录层级，如果要按保持原有的目录结构复制，可以设置rootdir参数：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">cp</span><span class="p">(</span><span class="s2">"src/**.h"</span><span class="p">,</span> <span class="s2">"/tmp/"</span><span class="p">,</span> <span class="p">{</span><span class="n">rootdir</span> <span class="o">=</span> <span class="s2">"src"</span><span class="p">})</span>
</code></pre>
</div>

<p>上面的脚本可以按<code class="highlighter-rouge">src</code>根目录，将src下的所有子文件保持目录结构复制过去。</p>

<p>注：尽量使用<code class="highlighter-rouge">os.cp</code>接口，而不是<code class="highlighter-rouge">os.run("cp ..")</code>，这样更能保证平台一致性，实现跨平台构建描述。</p>

<h4 id="osrun">os.run</h4>

<p>此接口会安静运行原生shell命令，用于执行第三方的shell命令，但不会回显输出，仅仅在出错后，高亮输出错误信息。</p>

<p>此接口支持参数格式化、内置变量，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="c1">-- 格式化参数传入</span>
<span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"echo hello %s!"</span><span class="p">,</span> <span class="s2">"xmake"</span><span class="p">)</span>

<span class="c1">-- 列举构建目录文件</span>
<span class="n">os</span><span class="p">.</span><span class="n">run</span><span class="p">(</span><span class="s2">"ls -l $(buildir)"</span><span class="p">)</span>
</code></pre>
</div>

<h4 id="osexecv">os.execv</h4>

<p>此接口相比os.run，在执行过程中还会回显输出，并且参数是通过列表方式传入，更加的灵活。</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">execv</span><span class="p">(</span><span class="s2">"echo"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"hello"</span><span class="p">,</span> <span class="s2">"xmake!"</span><span class="p">})</span>
</code></pre>
</div>

<p>另外，此接口还支持一个可选的参数，用于传递设置：重定向输出，执行环境变量设置，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">os</span><span class="p">.</span><span class="n">execv</span><span class="p">(</span><span class="s2">"echo"</span><span class="p">,</span> <span class="p">{</span><span class="s2">"hello"</span><span class="p">,</span> <span class="s2">"xmake!"</span><span class="p">},</span> <span class="p">{</span><span class="n">stdout</span> <span class="o">=</span> <span class="n">outfile</span><span class="p">,</span> <span class="n">stderr</span> <span class="o">=</span> <span class="n">errfile</span><span class="p">,</span> <span class="n">envs</span> <span class="o">=</span> <span class="p">{</span><span class="n">PATH</span> <span class="o">=</span> <span class="s2">"xxx;xx"</span><span class="p">,</span> <span class="n">CFLAGS</span> <span class="o">=</span> <span class="s2">"xx"</span><span class="p">,</span> <span class="n">curdir</span> <span class="o">=</span> <span class="s2">"/tmp"</span><span class="p">}}</span>
</code></pre>
</div>

<p>其中，stdout和stderr参数用于传递重定向输出和错误输出，可以直接传入文件路径，也可以传入io.open打开的文件对象。</p>

<p>另外，如果想在这次执行中临时设置和改写一些环境变量，可以传递envs参数，里面的环境变量设置会替换已有的设置，但是不影响外层的执行环境，只影响当前命令。</p>

<p>我们也可以通过<code class="highlighter-rouge">os.getenvs()</code>接口获取当前所有的环境变量，然后改写部分后传入envs参数。</p>

<p>另外，还能通过curdir参数设置，在执行过程中修改子进程的工作目录。</p>

<p>其相关类似接口还有，os.runv, os.exec, os.execv, os.iorun, os.iorunv等等，比如os.iorun可以获取运行的输出内容。</p>

<p>这块的具体详情和差异，还有更多os接口，都可以到：<a href="https://xmake.io/#/zh-cn/manual/builtin_modules?id=os">os接口文档</a> 查看。</p>

<h4 id="ioreadfile">io.readfile</h4>

<p>此接口，从指定路径文件读取所有内容，我们可在不打开文件的情况下，直接读取整个文件的内容，更加的方便，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="kd">local</span> <span class="n">data</span> <span class="o">=</span> <span class="n">io</span><span class="p">.</span><span class="n">readfile</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">)</span>
</code></pre>
</div>

<h4 id="iowritefile">io.writefile</h4>

<p>此接口写入所有内容到指定路径文件，我们可在不打开文件的情况下，直接写入整个文件的内容，更加的方便，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="n">io</span><span class="p">.</span><span class="n">writefile</span><span class="p">(</span><span class="s2">"xxx.txt"</span><span class="p">,</span> <span class="s2">"all data"</span><span class="p">)</span>
</code></pre>
</div>

<h4 id="pathjoin">path.join</h4>

<p>此接口实现跨平台地路径拼接操作，将多个路径项进行追加拼接，由于<code class="highlighter-rouge">windows/unix</code>风格的路径差异，使用api来追加路径更加跨平台，例如：</p>

<div class="language-lua highlighter-rouge"><pre class="highlight"><code><span class="nb">print</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="s2">"$(tmpdir)"</span><span class="p">,</span> <span class="s2">"dir1"</span><span class="p">,</span> <span class="s2">"dir2"</span><span class="p">,</span> <span class="s2">"file.txt"</span><span class="p">))</span>
</code></pre>
</div>

<p>上述拼接在unix上相当于：<code class="highlighter-rouge">$(tmpdir)/dir1/dir2/file.txt</code>，而在windows上相当于：<code class="highlighter-rouge">$(tmpdir)\\dir1\\dir2\\file.txt</code></p>

<p>更多内置模块详情见：<a href="https://xmake.io/#/zh-cn/manual/builtin_modules">内置模块文档</a></p>

        </article>
        <hr>

        <!-- baidu ads -->
        

        <!-- reward -->
        <div style="text-align: center;">
            <button id="rewardButton" disable="enable" onclick="var qr = document.getElementById('QR'); if (qr.style.display === 'none') {qr.style.display='block';} else {qr.style.display='none'}">
              <span>赏</span>
            </button>
            <div id="QR" style="display: none;">
                <div id="wechat" style="display: inline-block">
                  <img id="wechat_qr" src="/static/img/weixin.png" alt="WeChat Pay"/>
                  <p>微信打赏</p>
                </div>
                <div id="alipay" style="display: inline-block">
                  <img id="alipay_qr" src="/static/img/alipay.png" alt="Alipay"/>
                  <p>支付宝打赏</p>
                </div>
            </div>
        </div>

        
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
            
            
                
            
        
            
        
        

        
        
            
        
            
            
            
                
                    
                        
                        <h2 id="similar_posts">相关文章</h2>
                        <ul>
                        
                        <li class="relatedPost">
                            <a href="/cn/2021/12/17/xmake-update-v2.6.2/">xmake v2.6.2 发布，新增 Linux 内核驱动模块构建支持
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/cn/2021/12/03/xmake-update-v2.6.1/">xmake v2.6.1 发布，使用 Lua5.4 运行时，Rust 和 C++ 混合编译支持
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/cn/2021/10/30/xmake-update-v2.5.9/">xmake v2.5.9 发布，改进 C++20 模块，并支持 Nim, Keil MDK 和 Unity Build
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/cn/2021/10/08/xmake-update-v2.5.8/">xmake v2.5.8 发布，新增 Pascal/Swig 程序和 Lua53 运行时支持
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
            
        
            
        
            
            
            
                
                    
                        
                        <li class="relatedPost">
                            <a href="/cn/2021/08/29/xmake-update-v2.5.7/">xmake v2.5.7 发布，包依赖锁定和 Vala/Metal 语言编译支持
                            
                            </a>
                        </li>
                        
                        
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
                
                    
                
                    
                
                    
                
                    
                
                    
                
            
            
        
        
            </ul>
        

        <div class="post-recent">
    <div class="pre">

        

        

        
        
        <p><strong>上一篇</strong> <a href="/cn/2020/07/04/byopen/">一个绕过移动端系统限制的dlopen库: byOpen</a></p>
        
    </div>

    <div class="nex">

        

        

        
        
        <p><strong>下一篇</strong> <a href="/cn/2020/07/28/xmake-update-v2.3.6/">xmake v2.3.6 发布, 新增fortran编译支持</a></p>
        
    </div>
</div>


        <h2 id="comments">评论</h2>
        






<div id="gitalk-container"></div>
<link rel="stylesheet" href="/css/gitalk.css">
<script src="/js/gitalk.min.js"></script>

<script>
const gitalk = new Gitalk({
  clientID: '73946dc1d9e2276ad0da',
  clientSecret: '12a3cb94361ba3ebc6ecb68cf80d592bfaa8106d',
  repo: 'tboox.github.io',
  owner: 'waruqi',
  admin: ['waruqi'],
  id: location.pathname,       
  language: 'zh-CN',
  distractionFreeMode: false  
})

gitalk.render('gitalk-container')
</script>





    </div>
    <button class="anchor"><i class="fa fa-anchor"></i></button>
    <div class="right">
        <div class="wrap">

            <!-- codefund ads -->
            

            <!-- Content -->
            <div class="side content">
                <div>
                    内容
                </div>
                <ul id="content-side" class="content-ul">
                    <li><a href="#english">English</a></li>
                    <li><a href="#similar_posts">相关文章</a></li>
                    <li><a href="#comments">评论</a></li>
                </ul>
            </div>


            <!-- baidu ads -->
            
            
            <br>
            <div class="side">
                <div>
                    <i class="fa fa-external-link"></i>
                    链接
                </div>
                <ul class="content-ul">
                  <li><a href="http://github.com/waruqi/tbox">tbox</a></li>
                  <li><a href="http://www.xmake.io">xmake</a></li>
                  <li><a href="https://github.com/waruqi">github</a></li>
                </ul>
            </div> 

            <!-- xmake courses -->
            <br>
            <div class="side">
                <div>
                    <i class="fa fa-external-link"></i>
                    xmake 入门课程
                </div>
                <a href="https://xmake.io/#/zh-cn/about/course" target="_blank">
                <img src="/static/img/xmake-course.png" alt="course" width="256" height="193">
                </a>
            </div>

            <!-- qqgroup -->
            <br>
            <div class="side">
                <div>
                    <i class="fa fa-external-link"></i>
                    技术交流群（QQ）
                </div>
                <img src="/static/img/qqgroup.png" alt="qqgroup" width="256" height="284">
            </div> 

            <!-- google ads -->
            

            <!-- baidu ads -->
            

        </div>
    </div>

    <!-- baidu ads -->
    
</div>
<script>
/**
 * target _blank
 */
(function() {
    var aTags = document.querySelectorAll('article a:not([id])')
    for (var i = 0; i < aTags.length; i++) {
        aTags[i].setAttribute('target', '_blank')
    }
}());
</script>
<script src="/js/pageContent.js " charset="utf-8"></script>



    <footer class="site-footer">
    <div class="wrapper">
        <p class="description">
             Copyright (c) 2016-2020 tboox.org 
        </p>
        <p class="contact">
            
            <a href="https://github.com/waruqi" title="GitHub"><i class="fa fa-github" aria-hidden="true"></i></a> 
             
            
            <a href="mailto:waruqi@gmail.com" title="email"><i class="fa fa-envelope-o" aria-hidden="true"></i></a> 
            
            
            <a href="https://twitter.com/waruqi" title="Twitter"><i class="fa fa-twitter" aria-hidden="true"></i></a> 
            
            <a href="/feed.xml" title="feed"><i class="fa fa-feed" aria-hidden="true"></i></a> 
        </p>
        <p class="power">
            <span>
                Site powered by <a href="https://jekyllrb.com/">Jekyll</a> & <a href="https://github.com/Gaohaoyang">HyG</a> & <a href="https://pages.github.com/">Github Pages</a>.
            </span>
        </p>
    </div>
</footer>

    <div class="back-to-top">
    <a href="#top" class="scroll">
        <i class="fa fa-arrow-up" aria-hidden="true"></i>
    </a>
</div>

    <script src=" /js/main.js " charset="utf-8"></script>
    <script src=" /js/scroll.min.js " charset="utf-8"></script>
  </body>

</html>
